'''
    项目的启动文件 start.py

    启动方法:
        win:
            python start.py
        linux:
            nohup python3 start.py &

    本项目的日志并不完善, 后续应该增加更加详细的日志系统
'''


import socket
import threading
import time

from laoyu_web.http_class import HttpRequest        # 请求类, 用于存储 http请求 信息
from laoyu_web.http_class import HttpResponse       # 响应类, 用于发送 http响应 信息
from laoyu_web.http_class import static_file_dict   # 静态文件表 类型: dict
from laoyu_web.http_class import api_dict           # 动态接口类 类型: dict
from laoyu_web.http_class import static_web_file    # 静态文件读取函数



def ctrl_cilent(conn, addr):
    print(f'[{int(time.time())}] {addr[0]}:{addr[1]} 已经和本服务建立tcp连接')
    with conn:
        try:
            data = conn.recv(8000)
        except ConnectionResetError as err:
            print(f'[{int(time.time())}] [ERROR] {addr[0]}:{addr[1]} {err}')
            return conn.close()      # 退出函数时关闭tcp占用
        if data == b'':
            return print(f'[{int(time.time())}] {addr[0]}:{addr[1]} 已经断开与本服务的tcp连接')
        data = data.decode('utf-8')

        httpReqObj = HttpRequest()
        httpReqObj.init(data)
        print(f'[{int(time.time())}] {addr} {httpReqObj.method} {httpReqObj.url}')

        # 设置响应头头参数
        httpResponseObj = HttpResponse()
        httpResponseObj.setConn(conn)

        if httpReqObj.url in static_file_dict:
            response_data = static_web_file(
                static_file_dict[httpReqObj.url]
            )
        elif httpReqObj.url in api_dict:
            response_data = api_dict[httpReqObj.url](httpReqObj, httpResponseObj)
        else:
            response_data = b'404 not found'
        httpResponseObj.send(response_data)

    print(f'[{int(time.time())}] {addr[0]}:{addr[1]} 已经断开与本服务的tcp连接')

print('网络摄像头项目')
print('作者: laoyu')
print('项目说明: ')
print('    使用python作为服务端')
print('    使用浏览器作为客户端')
print('    服务端负责:')
print('      - 登录接口')
print('      - 摄像头视频流推送功能')
print('    客户端负责:')
print('      - html/css 登录页面以及视频界面')
print('      - js/canvas 负责视频流的展示\n\n')


ser = socket.socket(
    socket.AF_INET,
    socket.SOCK_STREAM
)

print(f'[{int(time.time())}] 该服务程序正在启动 . . .')

with ser:
    ser.bind(('0.0.0.0', 8000))
    ser.listen()

    print(f'[{int(time.time())}] 该服务程序启动完成 ! !')

    while True:
        try:
            conn, addr = ser.accept()
        except KeyboardInterrupt:
            break
        cilent = threading.Thread(
            target=ctrl_cilent,
            args=(conn, addr)
        )
        cilent.start()


print(f'[{int(time.time())}] 该服务程序已关闭')








